/**
 * 链表的常见操作
 *  append(element) 向链表尾部添加一个新的项
 *  insert(position, element) 向链表特定的位置插入一个新的项
 *  `get(position) 获取对应元素位置的元素
 *  indexOf(element) 返回元素在链表中的索引 如果链表没有这个元素就返回-1
 *  update(position, element) 修改某个位置的元素
 *  removeAt(position) 从链表的特定位置移除一项
 * remove(element)` 从链表中移除一项。
 *  isEmpty 如果链表中不包含任何元素 返回true 如果链表长度大于 0 则返回false 检测链表是否为空
 *  size 返回链表长度 元素个数
 *  toString 
 */
class Node {
  constructor (data) {
    this.data = data;
    this.next = null;
  }
}
class LinkedList {
  constructor () {
    this.length = 0
    // 链表的头节点
    this.head = null
  }
  // 向链表尾部插入一个元素
  append (data) {
    let newNode = new Node(data)
    if (this.head === null) {
      this.head = newNode
    } else {
      let currentNode = this.head
      while (currentNode.next !== null) {
        currentNode = currentNode.next
      }
      currentNode.next = newNode
    }
    this.length++
  }
  // 向链表指定位置插入一个新的项
  insert (position, data) {
    // position 新插入节点的位置
    // position = 0 表示新插入后是第一个节点
    // position = 1 表示新插入后是第二个节点，以此类推

    // 1、对 position 进行越界判断，不能小于 0 或大于链表长度
    if (position < 0 || position > this.length) return false;

    // 2、创建新节点
    const newNode = new Node(data);

    // 3、插入节点
    if (position === 0) { // position = 0 的情况
      // 让新节点的 next 指向 原来的第一个节点，即 head
      newNode.next = this.head;

      // head 赋值为 newNode
      this.head = newNode;
    } else { // 0 < position <= length 的情况

      // 初始化一些变量
      let currentNode = this.head; // 当前节点初始化为 head
      let previousNode = null; // head 的 上一节点为 null
      let index = 0; // head 的 index 为 0

      // 在 0 ~ position 之间遍历，不断地更新 currentNode 和 previousNode
      // 直到找到要插入的位置
      while (index++ < position) {
        previousNode = currentNode;
        currentNode = currentNode.next;
      }

      // 在当前节点和当前节点的上一节点之间插入新节点，即它们的改变指向
      newNode.next = currentNode;
      previousNode.next = newNode;
    }

    // 更新链表长度
    this.length++;
    return newNode;
  }
  // 获取对应位置的元素
  get (position) {
    if (position < 0 || position > this.length) return false
    let index = 0
    let currentNode = this.head
    if (position === 0) {
      return currentNode
    } else {
      // 遍历整个链表  获取链表指定位置的数据
      while (index < position) {
        currentNode = currentNode.next
        index++
      }
      return currentNode
    }
  }
  // 返回元素在链表中的索引 如果链表中没有该元素就返回-1
  indexOf (data) {
    let currentNode = this.head
    let index = 0
    while (currentNode.next !== null) {
      if (currentNode.data === data) {
        return index
      }
      currentNode = currentNode.next
      index++
    }
    return -1
  }
  // 从链表指定位置移除一项
  removeAt (position) {
    // 判断position是否符合要求
    if (position < 0 || position > this.length) return false
    let prevNode = null
    let currNode = this.head
    let index = 0
    if (position === 0) {
      this.head = currNode.next
    }
    while (index < position) {
      prevNode = currNode
      currNode = currNode.next
      index++
    }
    prevNode.next = currNode.next
    return currNode
  }
  // 判断链表是否为空
  isEmpty () {
    return this.length === 0 ? true : false
  }
  // 返回链表包含的元素个数
  size () {
    return this.length
  }
  toString () {
    let currentNode = this.head
    let result = " "
    while (currentNode) {
      console.log(currentNode.data, 'currentNode.data');
      result += currentNode.data + " "
      currentNode = currentNode.next
    }
    return result
  }
}
module.exports = {
  Node,
  LinkedList
}
//  测试代码
let linkedList = new LinkedList()
linkedList.append(1)
linkedList.append(2)
linkedList.append(3)
linkedList.append(4)
linkedList.append(5)
console.log(JSON.stringify(linkedList.head));
function reverseLinnkedList (head, k) {
  if (!head || k > head.length) {
    return head
  }
  
}
// linkedList.insert(0, 'B')
// linkedList.append('CC')
// console.log(linkedList);
// console.log(linkedList.get(2));
// console.log(linkedList.size());
// console.log(linkedList.indexOf('B'));
// console.log(linkedList.removeAt(2));
// console.log(linkedList);
// console.log(linkedList.isEmpty());
// console.log(linkedList);
// console.log(linkedList.toString());